#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

// 进程替换函数 ---- execl
//int main()
//{
//    pid_t pid = fork();
//
//    if (pid == 0)
//    {
//        // 子进程
//        printf("I am child. My pid is %d. My ppid is %d\n", getpid(), getppid());
//
//        // 进程替换
//        execl("/usr/bin/ls", "ls", "-a", "-l", NULL);
//        
//        printf("I am child. bye!!!");
//        exit(0);
//    }
//    else 
//    {
//        pid_t res = waitpid(pid, NULL, 0);
//        if (res == pid) // 进程回收成功
//        {
//            printf("我是父进程。子进程回收成功: %d\n", res);
//        }
//    }
//    return 0;
//}

// 进程替换函数 ---- execlp
//int main()
//{
//    pid_t pid = fork();
//
//    if (pid == 0)
//    {
//        // 子进程
//        printf("I am child. My pid is %d. My ppid is %d\n", getpid(), getppid());
//
//        // 进程替换函数execlp
//        execlp("ls", "ls", "-l", "-a", NULL);
//        
//        printf("I am child. bye!!!");
//        exit(0);
//    }
//    else 
//    {
//        pid_t res = waitpid(pid, NULL, 0);
//        if (res == pid) // 进程回收成功
//        {
//            printf("我是父进程。子进程回收成功: %d\n", res);
//        }
//    }
//    return 0;
//}

// 进程替换函数 - execv
//int main()
//{
//    pid_t pid = fork();
//
//    if (pid == 0)
//    {
//        // 子进程
//        printf("I am child. My pid is %d. My ppid is %d\n", getpid(), getppid());
//
//        // 进程替换函数execv
//        char* const argv[] = {"ls", "-a", "-l", NULL};
//
//        execv("/usr/bin/ls",argv);
//        
//        printf("I am child. bye!!!\n");
//
//        exit(0);
//    }
//    else 
//    {
//        pid_t res = waitpid(pid, NULL, 0);
//        if (res == pid) // 进程回收成功
//        {
//            printf("我是父进程。子进程回收成功: %d\n", res);
//        }
//    }
//    return 0;
//}

// 替换函数 --- execvp
//int main()
//{
//    pid_t pid = fork();
//
//    if (pid == 0)
//    {
//        // 子进程
//        printf("I am child. My pid is %d. My ppid is %d\n", getpid(), getppid());
//
//        // 进程替换函数execvp
//        char* const argv[] = {"ls", "-a", "-l", NULL};
//
//        execvp("ls",argv);
//        
//        printf("I am child. bye!!!\n");
//
//        exit(0);
//    }
//    else 
//    {
//        pid_t res = waitpid(pid, NULL, 0);
//        if (res == pid) // 进程回收成功
//        {
//            printf("我是父进程。子进程回收成功: %d\n", res);
//        }
//    }
//    return 0;
//}

// 使用execl调用别的程序

//int main()
//{
//    pid_t pid = fork();
//
//    if (pid == 0)
//    {
//        // 子进程
//        printf("I am child. My pid is %d. My ppid is %d\n", getpid(), getppid());
//
//        // 1. 调用C++程序
//        execl("./a.out", "a.out", NULL);
//        
//        printf("I am child. bye!!!\n");
//
//        exit(0);
//    }
//    else 
//    {
//        pid_t res = waitpid(pid, NULL, 0);
//        if (res == pid) // 进程回收成功
//        {
//            printf("我是父进程。子进程回收成功: %d\n", res);
//        }
//    }
//    return 0;
//}

// execle函数 

//int main()
//{
//    pid_t pid = fork();
//
//    if (pid == 0)
//    {
//        // 子进程
//        printf("I am child. My pid is %d. My ppid is %d\n", getpid(), getppid());
//
//        // execle函数
//        //extern char** environ;
//        //execle("./a.out", "a.out", "-a", "-b", "-c", NULL, environ);// 继承父进程环境变量
//        char* const envp[] = {"hello=666", "hi=999", NULL};
//        execle("./a.out", "a.out", "-a", "-b", "-c", NULL, envp);
//        printf("I am child. bye!!!\n");
//
//        exit(0);
//    }
//    else 
//    {
//        pid_t res = waitpid(pid, NULL, 0);
//        if (res == pid) // 进程回收成功
//        {
//            printf("我是父进程。子进程回收成功: %d\n", res);
//        }
//    }
//    return 0;
//}

// execve函数

int main()
{
    pid_t pid = fork();

    if (pid == 0)
    {
        // 子进程
        printf("I am child. My pid is %d. My ppid is %d\n", getpid(), getppid());

        // execve
        //char* const envp[] = {"hello=666", "hi=999", NULL};
        //char* const myargv[] = {"a.out", "-a", "-b", "-c", NULL};
        char* const envp[] = {"hello=666", "hi=999", NULL};
        char* const myargv[] = {"ls", "-a", "-l", NULL};
        execve("/usr/bin/ls", myargv, envp);
       
        printf("I am child. bye!!!\n");

        exit(0);
    }
    else 
    {
        pid_t res = waitpid(pid, NULL, 0);
        if (res == pid) // 进程回收成功
        {
            printf("我是父进程。子进程回收成功: %d\n", res);
        }
    }
    return 0;
}

